package com.game.service.db;

import com.game.service.app.PostJson;
import com.game.service.app.Utils;
import com.game.service.beans.GameConfig;
import com.game.service.beans.UserInfo;
import com.game.service.game.redblack.match.MatchUser;
import com.game.service.game.turntable.config.PrizeDb;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.object.BatchSqlUpdate;

import javax.sql.DataSource;
import java.sql.Types;
import java.util.List;

import static com.game.service.define.RoomConfig.*;

public class UserScoreDaoImpl {
    private static UserScoreDaoImpl instance;
    private static JdbcTemplate jdbcTemplate;

    public static final String CHANGE_TYPE_LOGIN = "首次登录";
    public static final String CHANGE_TYPE_LOGIN_OFFLINE = "断线登录";
    public static final String CHANGE_TYPE_FEE = "参赛费";
    public static final String CHANGE_TYPE_WIN = "获得奖励";
    public static final String CHANGE_TYPE_EXIT = "主动退出";

    private UserScoreDaoImpl() {
    }

    public static UserScoreDaoImpl getInstance() {
        if (instance == null) {
            instance = new UserScoreDaoImpl();
            instance.init();
        }
        return instance;
    }

    private void init() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");//
        dataSource.setUrl(DB_URL);//
        dataSource.setUsername(DB_NAME);
        dataSource.setPassword(DB_PWD);
        jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);

    }

    /***
     *  玩家分数流水记录
     * @param info 变动信息
     */
    public void addUserScoreUpdate(UserScoreUpdate info) {
        String sql = "INSERT into `user_score_update` (uid,currentScore,changeType,location,score,changeScore,remark,createTime) VALUES(?,?,?,?,?,?,?,?);";
        Object[] obj = {info.getUid(), info.getCurrentScore(), info.getChangeType(), info.getLocation(), info.getScore(), info.getChangeScore(), info.getRemark(), Utils.getTime()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     *  玩家分数实时记录
     * @param pid 玩家id
     * @param postJson 分数json
     * @param jsonDesc 最后状态
     */
    public void updateUserScore(String pid, String postJson, String jsonDesc) {
        String sql = "UPDATE `user_score` SET postResult=0,postJson=?,jsonDesc=? WHERE pid=?;";
        jdbcTemplate.update(sql, postJson, jsonDesc, pid);
    }

    /***
     * 玩家退出
     * @param pid 玩家id
     * @param jsonDesc 退出类型,1.主动结算,2.系统结算,3.解锁结算
     */
    public void userExit(String pid, String jsonDesc) {
        String sql = "UPDATE `user_score` SET postResult=1,successTime=?,jsonDesc=? WHERE pid=? and postResult=0 ;";
        jdbcTemplate.update(sql, Utils.getTime(), jsonDesc, pid);
    }

    public void userExitBatch(List<UserInfo> userInfoList, String jsonDesc) {
        DataSource dataSource = jdbcTemplate.getDataSource();
        assert dataSource != null;
        BatchSqlUpdate bsu = new BatchSqlUpdate(dataSource, "UPDATE `user_score` SET postResult=1,successTime=?,jsonDesc=? WHERE pid=? and postResult=0 ;");
        bsu.setBatchSize(1000);
        bsu.setTypes(new int[]{Types.DATE, Types.VARCHAR, Types.VARCHAR});

        for (UserInfo user : userInfoList) {
            bsu.update(Utils.getTime(), jsonDesc, user.getUid());
        }
        bsu.flush();
    }


    /***
     * 新增玩家
     *
     * @param info 玩家信息
     */
    public void addUserScore(PostJson info) {
        String sql = "INSERT into `user_score` (pid,jsonDesc,postResult,addCurrentTimeMillis,postJson,postUrl,createTime) VALUES(?,?,?,?,?,?,?);";
        Object[] obj = {info.getPid(), info.getJsonDesc(), info.getPostResult(), info.getAddCurrentTimeMillis(), info.getPostJson(), info.getPostUrl(), Utils.getTime()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     * 获取玩家
     *
     * @param pid 玩家id
     */
    public PostJson getUserScore(String pid) {
        try {
            String sql = "SELECT * FROM `user_score` WHERE pid=?;";
            return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(PostJson.class), pid);
        } catch (Exception e) {
            return null;
        }
    }

    /***
     * 发送总服务器的请求,保存
     * @param info 请求信息
     */

    public void addLog(PostJson info) {
        String sql = "INSERT into `post_json` (pid,gameid,uid,jsonDesc,postResult,addCurrentTimeMillis,postJson,postUrl,createTime) VALUES(?,?,?,?,?,?,?,?,?);";
        Object[] obj = {info.getPid(), info.getGameid(), info.getUid(), info.getJsonDesc(), info.getPostResult(), info.getAddCurrentTimeMillis(), info.getPostJson(), info.getPostUrl(), Utils.getTime()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     * 发送总服务器的请求,
     */
    public void updateLog(String pid) {
        String sql = "UPDATE `post_json` SET postResult=1,successTime=? WHERE pid=? and postResult=0;";
        jdbcTemplate.update(sql, Utils.getTime(), pid);
    }

    /***
     * 加载未处理的请求，再次发送
     * @return 未发送成功的list
     */
    public List<PostJson> getList(int gameid) {
        String sql = "SELECT * FROM `post_json` WHERE postResult=0 AND gameid=? LIMIT 100;";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(PostJson.class), gameid);
    }

    /***
     * 获取玩家-指定游戏的,游玩次数
     * @param gameid 游戏id
     * @param uid 用户id
     * @return 游玩次数
     */
    public int getPlayCounts(int gameid, int uid) {
        String sql = "SELECT COUNT(*) FROM `post_json` WHERE `gameid`=? AND uid=?;";
        return jdbcTemplate.queryForObject(sql, Integer.class, gameid, uid);
    }

    /***
     * 获取游戏配置
     * @param gameid 游戏id
     * @return 游玩次数
     */
    public GameConfig getGameConfig(int gameid) {
        GameConfig gameConfig = null;
        String sql = "SELECT * FROM `game_config` WHERE `gameid`=? ";
        try {
            gameConfig = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(GameConfig.class), gameid);
        } catch (Exception ignored) {

        }
        return gameConfig;
    }

    /***
     * 获取奖励列表
     * @param gameid 游戏id
     * @return 游玩信息
     */
    public PrizeDb getPrizeList(int gameid, int uid) {
        PrizeDb mPrizeDb = null;
        String sql = "SELECT * FROM `prize` WHERE `gameid`=? AND `uid`=? ";
        try {
            mPrizeDb = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(PrizeDb.class), gameid, uid);
        } catch (Exception ignored) {

        }
        return mPrizeDb;
    }

    /***
     * 新增玩家游玩奖励信息
     *
     * @param info 游玩奖励信息
     */
    public void addUserPrize(PrizeDb info) {
        String sql = "INSERT into `prize` (gameid,uid,prize_json,prize_daily_json) VALUES(?,?,?,?);";
        Object[] obj = {info.getGameid(), info.getUid(), info.getPrize_json(), info.getPrize_daily_json()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     * 更新玩家游玩奖励信息
     *
     * @param info 游玩奖励信息
     */
    public void updateUserPrize(PrizeDb info) {
        String sql = "UPDATE `prize`SET prize_json=?,prize_daily_json=? WHERE gameid=? and uid=? ;";
        Object[] obj = {info.getPrize_json(), info.getPrize_daily_json(), info.getGameid(), info.getUid()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     * 统计全部的运行信息
     * @return 发送成功的list
     */
    public List<PostJson> getGameRunInfoList(int gameid) {
        String sql = "SELECT * FROM `post_json` WHERE postResult=1 AND gameid=?;";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(PostJson.class), gameid);
    }

    /***
     *  统计特定时间的运行信息
     * @param gameid     哪款游戏
     * @param timeStart 开始时间
     * @param timeEnd  结束时间
     * @return list
     */
    public List<PostJson> getGameRunInfoList(int gameid, String timeStart, String timeEnd) {
        String sql = "SELECT * FROM `post_json` WHERE postResult=1 AND gameid=? AND createTime BETWEEN ? AND ?;";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(PostJson.class), gameid, timeStart, timeEnd);
    }
    //----------------------------------------------------邮件系统相关sql-----------------------------------

    /***
     * 发送总服务器的请求,保存
     * 邮件系统,执行逻辑，玩家完成游戏任务，获得奖励保存到邮件系统，等待发送
     * @param info 请求信息
     */

    public void addEmail(PostJson info) {
        String sql = "INSERT into `email` (pid,gameid,uid,jsonDesc,postResult,addCurrentTimeMillis,postJson,postUrl,createTime) VALUES(?,?,?,?,?,?,?,?,?);";
        Object[] obj = {info.getPid(), info.getGameid(), info.getUid(), info.getJsonDesc(), info.getPostResult(), info.getAddCurrentTimeMillis(), info.getPostJson(), info.getPostUrl(), Utils.getTime()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     * 加载邮件单条
     * @return 邮件list
     */
    public PostJson getEmail(String pid) {

        PostJson postJson = null;
        String sql = "SELECT * FROM `email` WHERE `pid`=? ";
        try {
            postJson = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(PostJson.class), pid);
        } catch (Exception ignored) {

        }
        return postJson;

    }

    /***
     * 加载邮件所有,设计为保留最近一个月的邮件
     * @return 邮件list
     */
    public List<PostJson> getEmailList(int gameid, int uid) {
        String sql = "SELECT * FROM `email` WHERE postResult !=2 AND gameid=? AND uid=? LIMIT 100;";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(PostJson.class), gameid, uid);
    }

    /***
     * 更新邮件处理状态为已经处理1
     */
    public void updateEmail(String pid) {
        String sql = "UPDATE `email` SET postResult=1,successTime=? WHERE pid=? and postResult=0;";
        jdbcTemplate.update(sql, Utils.getTime(), pid);
    }

    /***
     * 删除单条,实际上只是标记状态为2
     */
    public void deleteEmail(String pid) {
        String sql = "UPDATE `email` SET postResult=2 WHERE pid=? and postResult=1;";
        jdbcTemplate.update(sql, pid);
    }

    /***
     * 删除全部(特定用户),实际上只是标记状态为2
     */
    public void deleteAllEmail(int uid) {
        String sql = "UPDATE `email` SET postResult=2 WHERE uid=? and postResult=1;";
        jdbcTemplate.update(sql, uid);
    }
    //------------------------------------比赛 玩家信息记录--------------------------

    /***
     *
     * @param matchid 活动id
     * @param gameid 游戏id
     * @param info 比赛用户信息
     */
    public void addMatchUser(int matchid, int gameid, UserInfo info) {
        String sql = "INSERT into `match` (matchid,gameid,uid,name,uScore,match_limit,createTime) VALUES(?,?,?,?,?,?,?);";
        Object[] obj = {matchid, gameid, info.getUid(),info.getName(), info.getScore(),info.getPlayCounts(), Utils.getTime()};
        jdbcTemplate.update(sql, obj);
    }

    /***
     * 加载玩家比赛信息
     * @return 比赛玩家西信息
     */
    public MatchUser getMatchUser(int matchid, int gameid, int uid) {
        MatchUser matchUser = null;
        String sql = "SELECT * FROM `match` WHERE matchid=? and gameid=? and uid=?;";
        try {
            matchUser = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(MatchUser.class), matchid, gameid, uid);
        } catch (Exception ignored) {
        }
        return matchUser;
    }

    /***
     * 加载全部玩家比赛信息
     * @return List
     */
    public List<MatchUser> getMatchUserList(int matchid, int gameid) {
        String sql = "SELECT * FROM `match` WHERE matchid=? and gameid=? ;";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(MatchUser.class), matchid, gameid);
    }

    /***
     *
     * @param matchid 活动id
     * @param gameid 游戏id
     * @param info 比赛用户信息
     */
    public void updateMatchUser(int matchid, int gameid, UserInfo info) {
        String sql = "UPDATE `match` SET uScore=?,match_limit=? WHERE matchid=? and gameid=? and uid=?;";
        Object[] obj = {info.getScore(),info.getPlayCounts(), matchid, gameid, info.getUid()};
        jdbcTemplate.update(sql, obj);
    }
}
